<?php

namespace App\Http\Model;

use App\Lib\Snowflake\SnowflakeGenerator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class Guard extends Base
{
    protected $table = 'guard';
    protected $primaryKey = 'id';
    protected $guardStreamTable = 'guard_stream';
    protected $guardTypeTable = 'guard_type';

    protected $redisKeyGuard = 'CACHE:GUARD:';

    protected $tableDefaultField = [
        'guard_id', 'user_id', 'guard_user_id', 'guard_type_id', 'expire_time',
    ];

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
    }

    ########## 守护 ##################################################

    /**
     * 守护创建/更新
     * */
    public function upsertGuard($data, $type = 'insert')
    {
        $timestamp = time();

        switch ($type) {
            case 'insert':
                // 创建守护数据
                $ret = DB::table($this->table)->insertGetId([
                    'user_id' => $data['user_id'],
                    'guard_user_id' => $data['guard_user_id'],
                    'guard_type_id' => $data['guard_type_id'],
                    'expire_time' => $data['expire_time'],
                    'created_at' => $timestamp,
                    'updated_at' => $timestamp,
                ]);
                break;
            case 'update':// 该守护已过期，描述为续费标准 更新守护数据的新过期时间  expire_time 为过期时间戳
                $ret = DB::table($this->table)->where(['guard_id' => $data['guard_id']])->update([
                    'expire_time' => $data['expire_time'],
                    'updated_at' => $timestamp,
                ]);
                break;
            case 'increment':// 该守护未过期，描述为续费标准 累加守护过期时间  expire_time 为累加值秒数
                $ret = DB::table($this->table)->where(['guard_id' => $data['guard_id']])->increment('expire_time', $data['expire_time'], ['updated_at' => $timestamp]);

                $data['expire_time'] = $timestamp + $data['expire_time'];
                break;
            default:
                $ret = false;
                break;
        }

        if ($ret) {
            // 清除守护缓存数据
            Redis::del($this->redisKeyGuard . $data['user_id'] . '_' . $data['guard_user_id']);

            //增加一个track_id; add by zxiaofee
            $trackId = SnowflakeGenerator::generateId($this->guardStreamTable);
            // 创建守护流水数据
            DB::table($this->guardStreamTable)->insert([
                'track_id' => $trackId,
                'user_id' => $data['user_id'],
                'guard_user_id' => $data['guard_user_id'],
                'guard_type_id' => $data['guard_type_id'],
                'room_id' => $data['room_id'],
                'price' => $data['price'],
                'desc' => $data['desc'],
                'expire_time' => $data['expire_time'],
                'created_at' => $timestamp,
            ]);
        }

        return $ret;
    }

    /**
     * 查询守护数据（单条）
     * */
    public function getGuard($condition = [])
    {
        $ret = DB::table($this->table)->where($condition)->first($this->tableDefaultField);
        return self::objToArray($ret);
    }

    /**
     * 获取守护数据cache
     *
     * @param int $userId 守护者
     * @param int $guardUserId 被守护者
     * @return array
     * */
    public function getGuardDataCache($userId, $guardUserId)
    {
        do {
            $redisKey = $this->redisKeyGuard . $userId . '_' . $guardUserId;
            if (Redis::exists($redisKey)) {
                $data = json_decode(Redis::get($redisKey), true);
                break;
            }

            $data = $this->getGuardList([
                ['user_id', '=', $userId],
                ['guard_user_id', '=', $guardUserId],
                ['expire_time', '>', time()],
            ]);
            Redis::setex($redisKey, 3600, json_encode($data, JSON_UNESCAPED_UNICODE));

        } while (false);

        return $data;
    }


    /**
     * 判断是否有守护
     * @param $userId
     * @param $guardUserId
     * @param $guardType
     * @return bool
     */
    public function hasGuard($userId, $guardUserId, $guardTypeId)
    {
        $ret = DB::table($this->table)
            ->where('user_id', '=', $userId)
            ->where('guard_user_id', '=', $guardUserId)
            ->where('guard_type_id', '=', $guardTypeId)
            ->where('expire_time', '>=', time())
            ->count();
        if ($ret > 0) {
            return true;
        }
        return false;
    }

    /**
     * 查询守护数据（多条）
     * */
    public function getGuardList($condition = [], $orderBy = 'desc')
    {
        $this->tableDefaultField[] = $this->guardTypeTable . '.name';
        $this->tableDefaultField[] = $this->guardTypeTable . '.type';
        $this->tableDefaultField[] = $this->guardTypeTable . '.guard_img';
        $this->tableDefaultField[] = $this->guardTypeTable . '.guard_small_img';

        $db = DB::table($this->table)->where($condition);
        $ret = $db->leftJoin($this->guardTypeTable, 'guard_type_id', '=', 'type_id')
            ->orderBy($this->guardTypeTable . '.type', $orderBy)
            ->get($this->tableDefaultField)
            ->toArray();
        $ret = self::objToArray($ret);
        $this->guardTypeBuildImage($ret);

        return $ret;
    }

    /**
     * 分页分组查询守护数据（多条）
     * */
    public function getGuardPageList($condition = [], $page = 0, $limit = 10, $orderBy = 'desc')
    {
        $where = 'WHERE';
        foreach ($condition as $key => $value) {
            if (count($value) != 3) {
                continue;
            }
            if ($key == 0) {
                $where .= ' a.' . $value[0] . ' ' . $value[1] . ' ' . $value[2];
            } else {
                $where .= ' AND a.' . $value[0] . ' ' . $value[1] . ' ' . $value[2];
            }
        }

        $table = 'zb_' . $this->table . ' a';
        $leftJoin = "LEFT JOIN zb_" . $this->guardTypeTable . " b ON a.guard_type_id = b.type_id";
        $groupBy = "GROUP BY a.user_id";
        $orderBy = "ORDER BY type " . $orderBy . ",expire_time " . $orderBy;
        $offsetLimit = "LIMIT " . $page * $limit . "," . $limit;

        // 分组查询总条数
        $totalCount = DB::select("select count(*) as total from (select a.user_id from $table $where $groupBy) c");
        $totalCount = self::objToArray($totalCount)[0]['total'];

        // 分组分页查询数据
        $ret = DB::select("select a.user_id,max(b.type) as type,max(a.expire_time) as expire_time,GROUP_CONCAT(a.expire_time) as expire_time_all,GROUP_CONCAT(b.type) as type_all,GROUP_CONCAT(b.name) as type_name_all,GROUP_CONCAT(b.guard_img) as type_guard_img_all,GROUP_CONCAT(b.guard_small_img) as type_guard_small_img_all from $table $leftJoin $where $groupBy $orderBy $offsetLimit");
        $ret = self::objToArray($ret);

        return $this->checkPageData($page, $limit, $totalCount, $ret);
    }

    ########## 流水 ##################################################

    ########## 类型 ##################################################

    /**
     * 查询守护类型
     * */
    public function getGuardType($condition = [], $single = false, $orderBy = 'asc')
    {
        $db = DB::table($this->guardTypeTable)->where($condition);
        $ret = $db->orderBy('type', $orderBy)->get()->toArray();
        $ret = self::objToArray($ret);
        $this->guardTypeBuildImage($ret);

        if ($single) {
            $ret = $ret[0] ?? [];
        }

        return $ret;
    }

    /**
     * 守护类型图片构建完整地址
     * */
    protected function guardTypeBuildImage(&$data)
    {
        foreach ($data as $key => $value) {
            $data[$key]['guard_img'] = empty($value['guard_img']) ? '' : build_image($value['guard_img']);
            $data[$key]['guard_small_img'] = empty($value['guard_small_img']) ? '' : build_image($value['guard_small_img']);
        }
    }
}